package com.daiziru.wuyanmall.service.impl;

import com.daiziru.wuyanmall.dao.UsersMapper;
import com.daiziru.wuyanmall.entity.Users;
import com.daiziru.wuyanmall.service.UserService;
import com.daiziru.wuyanmall.utils.MD5Utils;
import com.daiziru.wuyanmall.vo.ResultStatus;
import com.daiziru.wuyanmall.vo.ResultVO;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.HashMap;
import java.util.List;

@Service//交给spring管理
@Scope("singleton")
public class UserServiceImpl implements UserService {

    @Autowired
    private UsersMapper usersMapper;//需要在userDAO实体类中加上一个@Respository，否则会爆红，但是这个爆红其实没有影响
    //用户注册
    @Transactional//把该方法定义为一个事务
    public ResultVO userResgit(String name, String pwd) {
        synchronized (this) {
            //1.根据用户名查询，这个用户是否已经被注册
            Example example = new Example(Users.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("username", name);
            List<Users> users = usersMapper.selectByExample(example);
            //2.如果没有被注册则进行保存操作
            if(users.size() == 0) {
                String md5Pwd = MD5Utils.md5(pwd); //MD5密码加密
                Users user = new Users();
                user.setUsername(name);
                user.setPassword(md5Pwd);
                user.setUserImg("img/default.jpg");
                user.setUserRegtime(new Date());
                user.setUserModtime(new Date());
                int i = usersMapper.insertUseGeneratedKeys(user);
                if(i > 0) {
                    return new ResultVO(ResultStatus.OK, "注册成功", user);
                } else {
                    return new ResultVO(ResultStatus.NO, "注册失败!", null);
                }
            } else {
                return new ResultVO(ResultStatus.NO, "用户名已经被注册!", null);
            }
        }
    }

    @Override
    public ResultVO checkLogin(String name, String pwd) {
        Example example = new Example(Users.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("username", name);
        List<Users> users = usersMapper.selectByExample(example);
        if(users.size() == 0) {
            return new ResultVO(ResultStatus.NO, "登录失败，用户名不存在!", null);
        } else {

            String md5Pwd = MD5Utils.md5(pwd);
            if(md5Pwd.equals(users.get(0).getPassword())) {
                //如果登录验证成功，则需要生成token(token就是按照一定规则生成的字符串)

//                String token = Base64Utils.encode(name + "975806");//按照规则生成token
                //JWT加密算法生成token
                JwtBuilder builder = Jwts.builder();
                HashMap<String, Object> map = new HashMap<>();
                map.put("key1", "value1");
                String token = builder.setSubject(name)                   //主题，就是token中携带的数据
                        .setIssuedAt(new Date())                          //设置token的⽣成时间
                        .setId(users.get(0).getUserId() + "")             //设置⽤户id为token id
                        .setClaims(map)                                   //map中可以存放⽤户的⻆⾊权限信息
                        .setExpiration(new Date(System.currentTimeMillis() + 24 * 60 * 60 * 1000)) //设置过期时间为1s,生成时间加一秒
                        .signWith(SignatureAlgorithm.HS256, "wuyan46") //设置加密⽅式和加密密码
                        .compact();//编写这个方法，返回一个字符串类型，否则返回的是builder
                return new ResultVO(ResultStatus.OK, token, users.get(0)); //token设置到msg中，传到前端页面
            } else {
                return new ResultVO(ResultStatus.NO, "登陆失败, 密码错误！", null);
            }

        }
    }
}
